package flexcommon.controls
{
  import mx.collections.ArrayCollection;
  import mx.controls.ComboBox;
  
  /**
   * Enhanced ComboBox control that can set its own selectedIndex based on a
   * specific value to examine (dataValue) with a particuliar field (dataField)
   * for each item in its dataProvider.
   * 
   * <p>Usages:</p>
   * 
   * <pre>
   * &lt;fx:DataComboBox id="countries"
   *  labelField="name"
   *  dataField="code"
   *  dataValue="{address.country}"
   *  change="address.country = countries.selectedItem.code;"&gt;
   *  &lt;fx:dataProvider&gt;
   *    &lt;mx:Array&gt;
   *      &lt;mx:Object code="CA" name="Canada"/&gt;
   *      &lt;mx:Object code="GR" name="Greece"/&gt;
   *      &lt;mx:Object code="US" name="United States"/&gt;
   *    &lt;/mx:Array&gt;
   *  &lt;/fx:dataProvider&gt;
   * &lt;/fx:DataComboBox&gt;
   * </pre>
   * 
   * <p>In the example above, once the country's address code is bounded to the 
   * dataValue property, it will set the selectedIndex based on a matching item 
   * in the dataProvider. The match is done by comparing the value of the dataValue 
   * property with the field named by dataField property ('code' in this case) 
   * with every object in the dataProvider.</p>
   * 
   * <p>Author: Dimitrios Gianninas</p>
   */
  public class DataComboBox extends ComboBox
  {
    private var _dataField:String;
    
    private var _dataValue:Object;
    
    /**
    * Default constructor.
    */
    public function DataComboBox()
    {
      super();
    }

    /**
     * Returns the value of the dataValue property.
     */
    public function get dataValue():Object
    {
      return _dataValue;
    }

    /**
     * The value to compare the dataField value against in order
     * to choose the appropriate selected index.
     */
    public function set dataValue(value:Object):void
    {
      _dataValue = value;
    }

    /**
     * Returns the value of the dataValue property.
     */
    public function get dataField():String
    {
      return _dataField;
    }

    /**
     * The property on the data items to examine.
     */
    public function set dataField(value:String):void
    {
      _dataField = value;
    }
    
    /**
     * Added code to set the appropriate selectedIndex based on
     * current dataValue property.
     */
    override protected function commitProperties():void
    {
      super.commitProperties();
      
      // if we have a dataProvider of type ArrayCollection
      // and we have a dataField specified then try to find
      // the correct selected index
      if( this.dataProvider != null 
        && this.dataProvider is ArrayCollection
        && _dataField != null ) 
      {
        var dpItem:Object;
        var dp:ArrayCollection = this.dataProvider as ArrayCollection;
        
        for( var idx:int = 0; idx < dp.length; idx++ )
        {
          dpItem = dp.getItemAt( idx );
          
          if( dpItem != null && dpItem[_dataField] == _dataValue )
          {
            this.selectedIndex = idx;
            return;
          }
        }
      }
    }

  }
}